#!/bin/bash

set -Eeuo pipefail
shopt -s inherit_errexit

function log() {
    local timestamp
    case "${CKI_LOGGING_FORMAT:-plain}" in
        json|pack)
            timestamp=$(date +%s.%N)
            echo '{"timestamp": "'"${timestamp}"'", "logger_name": "cki_lib.entrypoint", "logger_level": "INFO", "_entry": "'"$1"'"}'
            ;;
        *)
            timestamp=$(date -u +%FT%T.%6N)
            echo "${timestamp} - [INFO] - cki_lib.entrypoint - $1"
            ;;
    esac
}

function main() {
    # initialize kerberos keytab
    if [[ -r ${KRB_KEYTAB:-/keytab} ]]; then
        # shellcheck disable=SC2154
        kinit -t "${KRB_KEYTAB:-/keytab}" "${KRB_USER}" -l 7d
        if [[ ${KRB_REFRESH:-False} = [Tt]rue ]]; then
            python3 -m cki_lib.krb_ticket_refresher &
        fi
    fi

    readarray -t image_info_lines < <(cat /etc/cki-image 2> /dev/null || true)

    for line in "${image_info_lines[@]}"; do
        log "${line}"
    done

    timestamp=$(date -Iseconds)
    log "Started: ${timestamp}"

    log "PID shell: $$"

    if [[ -v START_REDIS ]]; then
        /usr/bin/redis-server /etc/redis/redis.conf &
        log "PID redis: $!"
    fi

    if [[ -v START_PHP ]]; then
        /usr/sbin/php-fpm --nodaemonize &
        log "PID php-fpm: $!"
    fi

    if [[ -v START_APACHE ]]; then
        httpd -D FOREGROUND &
        log "PID httpd: $!"
    fi

    # this needs to happen before other Python modules are started
    # so PROMETHEUS_MULTIPROC_DIR is exposed to them
    if [[ -v START_STANDALONE_METRICS_SERVER ]]; then
        export PROMETHEUS_MULTIPROC_DIR=/tmp/metrics
        rm -rf "${PROMETHEUS_MULTIPROC_DIR}"
        mkdir -p "${PROMETHEUS_MULTIPROC_DIR}"
        # shellcheck disable=SC2154
        gunicorn --bind "0.0.0.0:${CKI_METRICS_PORT}" --workers 1 "cki_lib.metrics.server:run" &
        log "PID metrics server: $!"
    fi

    for CELERY_VAR in "${!START_CELERY_@}"; do
        IFS=' ' read -r -a ARGS <<< "${!CELERY_VAR}"
        celery worker "${ARGS[@]}" &
        log "PID ${CELERY_VAR}: $!"
    done

    if [[ -v START_FLASK ]]; then
        if [[ ${CKI_DEPLOYMENT_ENVIRONMENT:-} = production ]] ; then
            gunicorn --bind 0.0.0.0:5000 --workers "${WEB_WORKERS:-2}" "${START_FLASK}:${FLASK_APP:-app}" &
        else
            FLASK_APP="${START_FLASK}:${FLASK_APP:-app}" FLASK_ENV=development flask run --host 0.0.0.0 --port 5000 &
        fi
        log "PID flask: $!"
    fi

    # shellcheck disable=SC2153
    for PYTHON_VAR in "${!START_PYTHON_@}"; do
        IFS=' ' read -r -a ARGS <<< "${!PYTHON_VAR}"
        python3 -m "${ARGS[@]}" &
        log "PID ${PYTHON_VAR}: $!"
    done

    # If even one process exits, kill all spawned processes
    log "Waiting for first process to exit"
    wait -n || true

    log "Killing process group: -$$"
    kill -- -$$
}

# all CKI images have a world-writable home directory at /cki
export HOME=/cki

# make getpwuid_r happy
if [[ -w /etc/passwd ]] && ! id -nu > /dev/null 2>&1; then
    user_id=$(id -u)
    group_id=$(id -g)
    echo "cki:x:${user_id}:${group_id}:,,,:${HOME}:/bin/bash" >> /etc/passwd;
fi

if [[ -v LOG_NAME ]]; then
    if [[ ${LOG_USE_HOSTNAME:-True} = [Tt]rue ]]; then
        LOG_PATH="/logs/${LOG_NAME}-${HOSTNAME}.log"
    else
        LOG_PATH="/logs/${LOG_NAME}.log"
    fi
    main 2>&1 | tee -a "${LOG_PATH}"
else
    main
fi &

# For ^C and SIGTERM for the container, kill the whole process group
trap 'trap - SIGINT SIGTERM && kill -- -$$' SIGINT SIGTERM
wait -n
